import NavHeader from '@/common/NavHeader'
import React, { Component } from 'react'
import style from './index.module.scss'
import { getCurrentCity } from '@/utils/city'
import axios from 'axios'
import { Toast } from 'antd-mobile'

const BMap = window.BMap
export default class Map extends Component {
  state = {
    isShow: false, // 控制房屋列表的展示
    houseList: [],
  }

  async componentDidMount() {
    // 1. 获取当前城市
    const city = await getCurrentCity()

    //创建地图实例
    this.map = new BMap.Map('container')
    // 将地址解析结果显示在地图上，并调整地图视野
    const myGeo = new BMap.Geocoder()
    myGeo.getPoint(
      city.label,
      async (point) => {
        //设置中心点坐标
        this.map.centerAndZoom(point, 11)
        // 添加地图控件
        this.map.addControl(new BMap.NavigationControl())
        this.map.addControl(new BMap.ScaleControl())

        // 给地图添加movestart事件, 地图移动事件
        this.map.addEventListener('movestart', () => {
          this.setState({
            isShow: false,
          })
        })

        //根据city.value,发送请求 渲染区覆盖物
        this.renderOverlays(city.value)
      },
      city.label
    )
  }
  //发送请求 渲染覆盖物
  async renderOverlays(id) {
    Toast.loading('加载中...', 0)
    //1.发送请求
    const res = await axios.get(`http://localhost:8080/area/map?id=${id}`)
    //2.获取列表
    const areas = res.data.body

    const { type, nextZoom } = this.getTypeAndZoom()
    // 3.遍历城市所有的区域，添加覆盖物
    areas.forEach((item) => {
      this.addOverlay(item, type, nextZoom)
    })

    Toast.hide()
  }

  //根据当前的缩放级别，得到下一级别的缩放级别和要渲染的覆盖物的类型
  getTypeAndZoom() {
    const zoom = this.map.getZoom()
    // console.log(zoom)
    let type, nextZoom
    if (zoom === 11) {
      type = 'circle'
      nextZoom = 13
    } else if (zoom === 13) {
      type = 'circle'
      nextZoom = 15
    } else {
      type = 'rect'
      nextZoom = 15
    }
    return {
      type,
      nextZoom,
    }
  }

  //封装一个方法 专门添加覆盖物
  addOverlay(item, type, nextZoom) {
    // console.log('需要渲染覆盖物', item, type, nextZoom)
    if (type === 'circle') {
      this.addCricle(item, nextZoom)
    } else {
      this.addRect(item, nextZoom)
    }
  }
  //渲染圆形覆盖物
  addCricle(item, nextZoom) {
    console.log('渲染圆形覆盖物', item, nextZoom)
    //1.区的所在位置
    const point = new BMap.Point(item.coord.longitude, item.coord.latitude)

    // 2.添加label标签 创建文本标注对象
    const label = new BMap.Label(
      `<div class="bubble">
    <p class="name">${item.label}</p>
    <p>${item.count}套</p>
  </div>`,
      {
        position: point, //指定文本标注所在的地理位置
        offset: new BMap.Size(-35, -35),
      }
    )
    //3.给覆盖物重置样式
    label.setStyle({
      border: 'none',
      padding: 0,
    })
    //4.往地图上添加覆盖物
    this.map.addOverlay(label)

    // 5.覆盖物添加点击事件
    label.addEventListener('click', () => {
      //5.1.以区为中心，展示并放大地图
      this.map.centerAndZoom(point, nextZoom)
      //5.2.清除原有的覆盖物
      setTimeout(() => {
        this.map.clearOverlays()
      }, 0)

      //5.3.根据当前区的id 发请求 渲染下一级的覆盖物
      this.renderOverlays(item.value)
    })
  }
  //渲染方形覆盖物
  addRect(item, nextZoom) {
    // console.log('渲染方形覆盖物', item, nextZoom)
    //1.区的所在位置
    const point = new BMap.Point(item.coord.longitude, item.coord.latitude)

    // 2.添加label标签 创建文本标注对象
    const label = new BMap.Label(
      `<div class="rect">
          <span class="housename">${item.label}</span>
          <span class="housenum">${item.count} 套</span>
          <i class="arrow"></i>
       </div>`,
      {
        position: point, //指定文本标注所在的地理位置
        offset: new BMap.Size(-50, -22),
      }
    )
    //3.给覆盖物重置样式
    label.setStyle({
      border: 'none',
      padding: 0,
    })
    //4.往地图上添加覆盖物
    this.map.addOverlay(label)

    // 5.覆盖物添加点击事件
    label.addEventListener('click', (e) => {
      Toast.loading('加载中...', 0)
      // 5.1 需要让地图居中，不需要放大了。不需要清除覆盖物
      const centerX = window.innerWidth / 2
      const centerY = (window.innerHeight - 45 - 330) / 2 + 45
      const x = centerX - e.changedTouches[0].pageX
      const y = centerY - e.changedTouches[0].pageY
      this.map.panBy(x, y)

      // 5.2 发送请求，显示该小区下的房源信息
      axios
        .get(`http://localhost:8080/houses?cityId=${item.value}`)
        .then((res) => {
          console.log(res)
          const houseList = res.data.body.list
          this.setState({
            houseList: houseList,
            isShow: true,
          })
          Toast.hide()
        })
    })
  }

  render() {
    return (
      <div className={style.map}>
        <NavHeader>地图找房</NavHeader>
        <div id="container" className="container"></div>
        {/* 更多房源 */}
        <div className={`houseList ${this.state.isShow ? 'show' : ''}`}>
          <div className="titleWrap">
            <h1 className="listTitle">房屋列表</h1>
            <a className="titleMore" href="/house/list">
              更多房源
            </a>
          </div>
          <div className="houseItems">
            {this.state.houseList.map((item) => (
              <div key={item.houseCode} className="house">
                <div className="imgWrap">
                  <img
                    className="img"
                    src="http://localhost:8080/newImg/7bi0l6e09.jpg"
                    alt=""
                  />
                </div>
                <div className="content">
                  <h3 className="title">{item.title}</h3>
                  <div className="desc">{item.desc}</div>
                  <div>
                    {item.tags.map((tag, index) => {
                      const tagClassName = 'tag tag' + ((index % 3) + 1)
                      return (
                        <span key={tag} className={tagClassName}>
                          {tag}
                        </span>
                      )
                    })}
                  </div>
                  <div className="price">
                    <span className="priceNum">{item.price}</span> 元/月
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>
    )
  }
}
